package com.gitee.neuray.security.admin.executor.handler;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.gitee.neuray.security.admin.executor.dingding.entity.StaffVO;
import com.gitee.neuray.security.admin.executor.dingding.mapper.DingdingMapper;
import com.taobao.api.ApiException;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther: liln
 * @date: 2020/3/4 15:19
 * @description:
 */
@Component
@Slf4j
public class DingdingTaskJob {
  @Value("${dingding.appkey}")
  private  String appKey;
  @Value("${dingding.appsecrect}")
  private  String appSecre ;
  private static String token; // token
  @Autowired private DingdingMapper ddMaper;
  /** 定时同步钉钉人员信息 */
  @XxlJob("dingdingTasHandler")
  public ReturnT<String> DingdingTasHandler(String param) throws Exception {
    XxlJobLogger.log(">>>>>>>>>>>>>>>>>>>>>>>>定时同步钉钉人员信息......");
    getTocekn(); // 获取Token
    syncUsers(); // 同步在职人员信息
    syncQuitUsers(); // 同步离职人员信息
    return ReturnT.SUCCESS;
  }

  public void getTocekn() {
    try {
      // 通过appKey和Appsecret 获取token
      DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
      OapiGettokenRequest req = new OapiGettokenRequest();
      req.setAppkey(appKey);
      req.setAppsecret(appSecre);
      req.setHttpMethod("GET");
      OapiGettokenResponse rsp = client.execute(req);
      XxlJobLogger.log(">>>>>>>>>>>>>>>获取token......" + rsp.getBody());
      token = rsp.getAccessToken();
    } catch (ApiException e) {
      e.printStackTrace();
    }
  }
  /**
   * 时间 2020/2/28
   *
   * @author 同步用戶信息
   */
  public void syncUsers() throws Exception {

    // 获取在职员工
    List<String> userId = new ArrayList<>();
    List<String> zzUserIds = getZzYg(userId, 0L); // 获取在职员工userID集合
    XxlJobLogger.log(">>>>>>>>>>>>>需要同步在职人员......" + zzUserIds.size() + "条记录");
    // 通过token和员工userId获取用户花名册
    List<OapiSmartworkHrmEmployeeListResponse.EmpFieldInfoVO> userInfo =
        new ArrayList<>(); // 员工花名册集合
    DingTalkClient client =
        new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/list");
    OapiSmartworkHrmEmployeeListRequest reqHmc = new OapiSmartworkHrmEmployeeListRequest();
    for (int i = 0; i < zzUserIds.size(); i++) {
      reqHmc.setUseridList(zzUserIds.get(i).replace("[", "").replace("]", ""));
      OapiSmartworkHrmEmployeeListResponse rspHmc = client.execute(reqHmc, token);
      userInfo.add(rspHmc.getResult().get(0));
    }
    // 将同步的人员花名册集合插入数据库
    if (userInfo.size() > 0) {
      userInfoInsertDB(userInfo);
    }
  }

  /**
   * 时间 2020/2/28
   *
   * @author 同步离职用戶信息
   */
  public void syncQuitUsers() throws Exception {
    // 获取在职员工
    List<String> userId = new ArrayList<>();
    List<String> lzYgIds = getLzYg(userId, 0L); // 获取在职员工userID集合
    List<OapiSmartworkHrmEmployeeListdimissionResponse.EmpDimissionInfoVo> lzryInfo =
        new ArrayList<>(); // 员工花名册集合
    DingTalkClient client =
        new DefaultDingTalkClient(
            "https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/listdimission");
    OapiSmartworkHrmEmployeeListdimissionRequest req =
        new OapiSmartworkHrmEmployeeListdimissionRequest();

    // 校验离职人员信息是否在系统中
    for (int i = 0; i < lzYgIds.size(); i++) {
      // 校验人员信息是否存在
      int num = ddMaper.checkUserOnly(lzYgIds.get(i));
      if (num != 0) { // 如果存在
        req.setUseridList(lzYgIds.get(i).replace("[", "").replace("]", ""));
        OapiSmartworkHrmEmployeeListdimissionResponse rsp = client.execute(req, token);
        if (rsp.getResult().size() > 0) { // 如果能获取离职信息
          lzryInfo.add(rsp.getResult().get(0));
        } else {
          continue;
        }
      } else {
        continue;
      }
    }
    XxlJobLogger.log(">>>>>>>>>>>>>需要同步离职人员......" + lzryInfo.size() + "条记录");
    // 更新离职信息
    if (lzryInfo.size() > 0) {
      ddMaper.updLzxx(lzryInfo);
    }
  }

  /** 将同步的人员花名册集合插入数据库 */
  public void userInfoInsertDB(List<OapiSmartworkHrmEmployeeListResponse.EmpFieldInfoVO> userInfo)
      throws ParseException, Exception {

    List<StaffVO> staffList = new ArrayList<>(); // 人员信息LIST
    String syncUsers = ""; // 同步人员
    try {
      for (OapiSmartworkHrmEmployeeListResponse.EmpFieldInfoVO list : userInfo) { // 遍历人员集合
        StaffVO staffVO = new StaffVO();
        staffVO.setUserId(list.getUserid()); // 获取userID
        staffVO.setId(list.getUserid()); // 将UserId 赋值到 id字段，保证唯一性
        for (OapiSmartworkHrmEmployeeListResponse.EmpFieldVO oneUserList :
            list.getFieldList()) { // 遍历每个人的字段信息
          staffVO = setStaffVo(oneUserList, staffVO); // 将钉钉字段信息赋值到StaffVo
        }
        syncUsers += staffVO.getName() + ","; //
        staffVO.setPhone((staffVO.getPhone()==null)?"":(staffVO.getPhone().replace("-","")));
        staffList.add(staffVO);
      }
      // 批量操作数据库
      if (staffList != null && staffList.size() > 0) {
        ddMaper.staffInfoInsertDB(staffList);
        XxlJobLogger.log(
            ">>>>>>>>>>>>>>>>>>>>>>>>定时同步钉钉人员信息成功，总计同步"
                + staffList.size()
                + "条数据,同步人员:"
                + syncUsers.substring(0, syncUsers.length() - 1));
      }
      XxlJobLogger.log(">>>>>>>>>>>>>>>>>>>>>>>>定时同步钉钉人员信息结束");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /*
   * @author wwj 获取在职员工userID集合
   */
  public List<String> getZzYg(List<String> userIds, Long offset) {
    try {
      // 获取在职员工
      DingTalkClient client =
          new DefaultDingTalkClient(
              "https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob");
      OapiSmartworkHrmEmployeeQueryonjobRequest reqZzYz =
          new OapiSmartworkHrmEmployeeQueryonjobRequest();
      reqZzYz.setStatusList("2,3");
      reqZzYz.setOffset(offset);
      reqZzYz.setSize(50L);
      OapiSmartworkHrmEmployeeQueryonjobResponse rspZzYz = client.execute(reqZzYz, token);
      XxlJobLogger.log(">>>>>>>>>>>>>>>>>>>>>>>>定时同步获取在职人员" + rspZzYz.getBody());

      // 校验人员是否已经同步过
      for (int i = 0; i < rspZzYz.getResult().getDataList().size(); i++) {
        // 校验人员信息是否存在
        int num = ddMaper.checkUserOnly(rspZzYz.getResult().getDataList().get(i));
        if (num != 0) {
          continue; // 存在先跳出
        }
        userIds.add(rspZzYz.getResult().getDataList().get(i));
      }
      if (rspZzYz.getResult().getNextCursor() != null) {
        getZzYg(userIds, rspZzYz.getResult().getNextCursor());
      }
    } catch (ApiException e) {
      e.printStackTrace();
    }
    return userIds;
  }
  /**
   * 时间 2020/3/3
   *
   * @author wwj 获取离职员工
   */
  public List<String> getLzYg(List<String> userIds, Long offset) {
    try {
      // 获取离职员工
      DingTalkClient client =
          new DefaultDingTalkClient(
              "https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
      OapiSmartworkHrmEmployeeQuerydimissionRequest req =
          new OapiSmartworkHrmEmployeeQuerydimissionRequest();
      req.setOffset(0L);
      req.setSize(50L);
      OapiSmartworkHrmEmployeeQuerydimissionResponse rsp = client.execute(req, token);
      XxlJobLogger.log(">>>>>>>>>>>>>>>>>>>>>>>>获取离职人员" + rsp.getBody());
      // 取出离职员工的集合并融合
      userIds.addAll(rsp.getResult().getDataList());
      if (rsp.getResult().getNextCursor() != null) {
        getZzYg(userIds, rsp.getResult().getNextCursor());
      }
    } catch (ApiException e) {
      e.printStackTrace();
    }
    return userIds;
  }
  /**
   * 将钉钉字段信息赋值到setStaffVo
   *
   * @param oneUserList
   */
  public StaffVO setStaffVo(
      OapiSmartworkHrmEmployeeListResponse.EmpFieldVO oneUserList, StaffVO staff)
      throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    if ("姓名".equals(oneUserList.getFieldName())) {
      staff.setName(oneUserList.getLabel());
    }
    if ("邮箱".equals(oneUserList.getFieldName())) {
      staff.setEmail(oneUserList.getLabel());
      if (oneUserList.getLabel() != null && !"".equals(oneUserList.getLabel())) {
        staff.setAccout((oneUserList.getLabel()).split("@")[0]); // 账号
      }
      staff.setPassword(
          "$2a$12$NelDp8G0VH0Ju19SJBTR/.1Jyiw.Lks/i7zi7TKIZmEjpTT6so7xe"); // 密码 123456
    }
    if ("主部门id".equals(oneUserList.getFieldName())) {
      staff.setDeptCode(oneUserList.getLabel());
    }
    if ("职位".equals(oneUserList.getFieldName())) {
      staff.setPosition(oneUserList.getLabel());
    }
    if ("手机号".equals(oneUserList.getFieldName())) {
      staff.setPhone(oneUserList.getLabel().replace("+86", "").replace(" ", ""));
    }
    if ("办公地点".equals(oneUserList.getFieldName())) {
      staff.setBgdd(oneUserList.getLabel());
    }
    if ("入职时间".equals(oneUserList.getFieldName())) {
      staff.setRzsj(oneUserList.getLabel());
      if (oneUserList.getLabel() != null) {
        staff.setSl(dayComparePrecise(sdf.format(new Date()), oneUserList.getLabel())); // 司龄
      }
    }
    if ("社保缴纳地".equals(oneUserList.getFieldName())) {
      staff.setSbjnd(oneUserList.getLabel());
    }
    if ("员工类型".equals(oneUserList.getFieldName())) {
      staff.setYglx(oneUserList.getLabel());
    }
    if ("试用期".equals(oneUserList.getFieldName())) {
      staff.setSyq(oneUserList.getLabel());
    }
    if ("转正日期".equals(oneUserList.getFieldName())) {
      staff.setZzrq(oneUserList.getLabel());
    }
    if ("岗位职级".equals(oneUserList.getFieldName())) {
      staff.setGwzj(oneUserList.getLabel());
    }
    if ("身份证姓名".equals(oneUserList.getFieldName())) {
      staff.setSfzxm(oneUserList.getLabel());
    }
    if ("证件号码".equals(oneUserList.getFieldName())) {
      staff.setZjhm(oneUserList.getLabel());
    }
    if ("出生日期".equals(oneUserList.getFieldName())) {
      staff.setCsrq(oneUserList.getLabel());
      if (oneUserList.getLabel() != null) {
        staff.setAge(
            (dayComparePrecise(sdf.format(new Date()), oneUserList.getLabel())).split("年")[0]
                + "岁"); // 年龄
      }
    }
    if ("性别".equals(oneUserList.getFieldName())) {
      staff.setSex(oneUserList.getLabel());
    }
    if ("民族".equals(oneUserList.getFieldName())) {
      staff.setNation(oneUserList.getLabel());
    }
    if ("身份证地址".equals(oneUserList.getFieldName())) {
      staff.setSfzdz(oneUserList.getLabel());
    }
    if ("证件有效期".equals(oneUserList.getFieldName())) {
      staff.setZjyxq(oneUserList.getLabel());
    }
    if ("婚姻状况".equals(oneUserList.getFieldName())) {
      staff.setHyzk(oneUserList.getLabel());
    }
    if ("首次参加工作时间".equals(oneUserList.getFieldName())) {
      staff.setSccjgzsj(oneUserList.getLabel());
      if (oneUserList.getLabel() != null) {
        staff.setGl(dayComparePrecise(sdf.format(new Date()), oneUserList.getLabel())); // 工龄
      }
    }
    if ("户籍类型".equals(oneUserList.getFieldName())) {
      staff.setHjlx(oneUserList.getLabel());
    }
    if ("住址".equals(oneUserList.getFieldName())) {
      staff.setZz(oneUserList.getLabel());
    }
    if ("政治面貌".equals(oneUserList.getFieldName())) {
      staff.setZzmm(oneUserList.getLabel());
    }
    if ("学历".equals(oneUserList.getFieldName())) {
      staff.setXl(oneUserList.getLabel());
    }
    if ("毕业院校".equals(oneUserList.getFieldName())) {
      staff.setByyx(oneUserList.getLabel());
    }
    if ("毕业时间".equals(oneUserList.getFieldName())) {
      staff.setBysj(oneUserList.getLabel());
    }
    if ("所学专业".equals(oneUserList.getFieldName())) {
      staff.setSxzy(oneUserList.getLabel());
    }
    if ("银行卡号".equals(oneUserList.getFieldName())) {
      staff.setYhkh(oneUserList.getLabel());
    }
    if ("开户行".equals(oneUserList.getFieldName())) {
      staff.setKhh(oneUserList.getLabel());
    }
    if ("合同公司".equals(oneUserList.getFieldName())) {
      staff.setHtgs(oneUserList.getLabel());
    }
    if ("合同类型".equals(oneUserList.getFieldName())) {
      staff.setHtlx(oneUserList.getLabel());
    }
    if ("首次合同起始日".equals(oneUserList.getFieldName())) {
      staff.setSchtqsr(oneUserList.getLabel());
    }
    if ("首次合同到期日".equals(oneUserList.getFieldName())) {
      staff.setSchtdqr(oneUserList.getLabel());
    }
    if ("现合同起始日".equals(oneUserList.getFieldName())) {
      staff.setXhtqsr(oneUserList.getLabel());
    }
    if ("现合同到期日".equals(oneUserList.getFieldName())) {
      staff.setXhtdqr(oneUserList.getLabel());
    }
    if ("合同期限".equals(oneUserList.getFieldName())) {
      staff.setHtqx(oneUserList.getLabel());
    }
    if ("续签次数".equals(oneUserList.getFieldName())) {
      staff.setXqcs(oneUserList.getLabel());
    }
    if ("紧急联系人姓名".equals(oneUserList.getFieldName())) {
      staff.setJjlxrxm(oneUserList.getLabel());
    }
    if ("联系人关系".equals(oneUserList.getFieldName())) {
      staff.setLsxgx(oneUserList.getLabel());
    }
    if ("联系人电话".equals(oneUserList.getFieldName())) {
      staff.setLsxdh(oneUserList.getLabel());
    }
    if ("家人姓名".equals(oneUserList.getFieldName())) {
      staff.setJrxm(oneUserList.getLabel());
    }
    if ("家人关系".equals(oneUserList.getFieldName())) {
      staff.setJrgx(oneUserList.getLabel());
    }
    if ("员工状态".equals(oneUserList.getFieldName())) {
      staff.setYgzt(oneUserList.getLabel());
    }
    if ("离职日期".equals(oneUserList.getFieldName())) {
      staff.setLzsj(oneUserList.getLabel());
    }
    if ("离职原因".equals(oneUserList.getFieldName())) {
      staff.setLzyy(oneUserList.getLabel());
    }
    staff.setSjly("2"); // 数据来源 2 钉钉同步
    staff.setZzzt("1"); // 在职状态 1 在职
    return staff;
  }
  /**
   * 计算2个日期之间相差的 相差多少年月日 比如：2011-02-02 到 2017-03-02 相差 6年，1个月，0天
   *
   * @param fromDate YYYY-MM-DD
   * @param toDate YYYY-MM-DD
   * @return 年,月,日 例如 1,1,1
   */
  public String dayComparePrecise(String toDate, String fromDate) {

    Period period = Period.between(LocalDate.parse(fromDate), LocalDate.parse(toDate));

    StringBuffer sb = new StringBuffer();
    sb.append(period.getYears())
        .append("年")
        .append(period.getMonths())
        .append("月")
        .append(period.getDays())
        .append("天");
    return sb.toString();
  }
}
